/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.ppm.gtm.mas;

import bgu.ppm.gtm.agents.ExhaustiveAgent;
import bgu.ppm.gtm.base.GameTheoryModel;
import bgu.ppm.sim.api.exec.TickBasedExecutable;
import bgu.ppm.sim.api.exec.TickBasedExecutionSystem;
import bgu.ppm.sim.api.mas.MultiAgentSystem;
import bgu.ppm.sim.api.mas.TerminationCondition;
import bgu.sonar.util.evt.EventListeners;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *
 * @author Vadim
 */
public class AllAgentsTerminatedTerminationCondition implements TerminationCondition {

    private EventListeners<TerminationListener> listeners = EventListeners.create(TerminationListener.class);
    private MultiAgentSystem system;
    private Set<TickBasedExecutable> executables;
    private int tick;
    private int amountOfNashes;
    private int amountOfNotNashes;

    @Override
    public void initialize(MultiAgentSystem system) {
        this.system = system;
        executables = new HashSet<>();

        tick = 0;

        amountOfNashes = 0;
        amountOfNotNashes = 0;
    }

    @Override
    public boolean shouldTerminate() {
        return executables.isEmpty();
    }

    @Override
    public EventListeners<TerminationListener> getListeners() {
        return listeners;
    }

    @Override
    public void beforeTick(TickBasedExecutionSystem execs, TickBasedExecutable executable) {
    }

    @Override
    public void afterTick(TickBasedExecutionSystem execs, TickBasedExecutable executable) {
        if (executable instanceof ExhaustiveAgent
                && system.getGlobalModel() instanceof GameTheoryModel) {
            try {
                GameTheoryModel model = (GameTheoryModel) system.getGlobalModel();
                boolean isPNE = model.isCurrentStrategyProfilePNE();
                amountOfNashes += isPNE ? 1 : 0;
                amountOfNotNashes += isPNE ? 0 : 1;
            } catch (Exception e) {
            }
        }
        // System.out.println("Ended tick: " + tick++);
    }

    @Override
    public void onExecutablesEnded(TickBasedExecutionSystem execs, List<TickBasedExecutable> executables) {
    }

    @Override
    public void beforeExecutableAdded(TickBasedExecutionSystem execs, TickBasedExecutable executable) {
    }

    @Override
    public void afterExecutableAdded(TickBasedExecutionSystem execs, TickBasedExecutable executable) {
        executables.add(executable);
    }

    @Override
    public void beforeExecutableRemoved(TickBasedExecutionSystem execs, TickBasedExecutable executable) {
    }

    @Override
    public void afterExecutableRemoved(TickBasedExecutionSystem execs, TickBasedExecutable executable) {
        executables.remove(executable);

        if (shouldTerminate()) {
            listeners.fire().onTerminationNeeded(this);

            System.out.println("PNEs: " + amountOfNashes + ", not PNEs: " + amountOfNotNashes);
        }
    }
}
